package xm.components.calendar
{
	import flash.events.Event;
	
	import xm.components.spinner.Spinner;
	import xm.components.spinner.SpinnerContainer;
	import xm.events.SpinnerEvent;
	import xm.util.DateUtil;
	
	
	/**
	 * <br> 클래스 설명 : </br>
	 * @author 김정환
	 */	
	public class CalendarSpinner extends SpinnerContainer
	{
		
		//-----------------------------------------------------------------------------------
		// public vars
		//-----------------------------------------------------------------------------------
		
		
		
		
		
		
		//-----------------------------------------------------------------------------------
		// protected / internal vars
		//-----------------------------------------------------------------------------------
		
		
		
		
		//-----------------------------------------------------------------------------------
		// private vars
		//-----------------------------------------------------------------------------------
		
		private var _currentYear : Number = -1;
		private var _currentMonth : Number = -1;
		private var _currentDate : Number = -1;
		
		private var _spinnerYear : Spinner;
		private var _spinnerMonth : Spinner;
		private var _spinnerDate : Spinner;
		
		
		//-----------------------------------------------------------------------------------
		// public functions
		//-----------------------------------------------------------------------------------
		
		/**
		 * constructor 
		 */	
		public function CalendarSpinner()
		{
			super( null );
		}
		
		
		/**
		 * commitProperties
		 */		
		override public function commitProperties():void
		{
			super.commitProperties();
			
		}
		
		
		
		/**
		 * updateDisplayList
		 */		
		override public function updateDisplayList( enforce : Boolean = false ):void
		{
			super.updateDisplayList(enforce);
			
		}
		
		
		
		
		
		/**
		 * 시작년도와 마지막년도 사이의 선택년도를 인자로 삽입.
		 * <br />
		 * @param startYear : int - 시작년도
		 * @param endYear : int - 마지막년도
		 * @param selectedYear : Number - 최초 선택년도
		 */		
		public function setYear( startYear : int, endYear : int, selectedYear : Number = 0 ):void
		{
			var i : int, len : int, year : int, dp : Array, selectedIndex : int;
			
			// year
			dp = [];
			year=startYear;
			len = endYear+1;
			
			if( selectedYear == -1 )
			{
				selectedYear = Number( new Date().fullYear );
			}
			
			_currentYear = selectedYear;
			
			while( year<len )
			{
				if( selectedYear == year ) selectedIndex = i;
				dp.push( String( year ) );
				
				++i;
				++year;
			}
			
			_spinnerYear = new Spinner();
			_spinnerYear.selectedIndex = selectedIndex;
			_spinnerYear.dataProvider = dp;
			_spinnerYear.invalidateDisplayList();
			_spinnerYear.addEventListener(SpinnerEvent.SPINNER_COMPLETE, onYearChange );
			addSpinner( _spinnerYear );
			
		}
			
		
		/**
		 * 0~11 선택월 삽입.
		 * @param selectedMonth : Number - 최초 선택월
		 */		
		public function setMonth( selectedMonth : Number = -1 ):void
		{
			var i : int, len : int, dp : Array, selectedIndex : int;
			
			// month
			dp = [];
			i=0;
			len = 12;
			
			if( selectedMonth == -1 )
			{
				selectedMonth = Number( new Date().month );
			}
			
			_currentMonth = selectedMonth;
			
			while( i<len )
			{
				if( selectedMonth == i ) selectedIndex = i;
				dp.push( String( i+1 ) );
				
				++i;
			}
			
			
			_spinnerMonth = new Spinner();
			_spinnerMonth.addEventListener(SpinnerEvent.SPINNER_COMPLETE, onMonthChange );
			_spinnerMonth.selectedIndex = selectedIndex;
			_spinnerMonth.dataProvider = dp;
			_spinnerMonth.invalidateDisplayList();
			addSpinner( _spinnerMonth );
			
		}
		
		
		/**
		 * setMonth() 가 선행되어야 함.
		 * <br />
		 * 월에 따른 최초 선택일. 
		 * <br />
		 * @param selectedDate : int = 최초선택일
		 */		
		public function setDate( selectedDate : Number = -1 ) : void
		{
			
			if( _currentMonth == -1 ) 
			{
				throw new Error( "currentMonth를 먼저 셋팅해 주세요" ); 
			}
			
			var i : int, len : int, dp : Array, selectedIndex : int;
			
			// month
			dp = [];
			i=0;
			len = int( DateUtil.getLastDateAtMonth( _currentMonth, _currentYear ) );
			
			if( selectedDate == -1 )
			{
				selectedDate = Number( new Date().date );
			}
			
			_currentDate = selectedDate;
			
			while( i<len )
			{
				if( selectedDate == i+1 ) selectedIndex = i;
				dp.push( String( i+1 ) );
				
				++i;
			}
			
			
			_spinnerDate = new Spinner();
			_spinnerDate.selectedIndex = selectedIndex;
			_spinnerDate.dataProvider = dp;
			_spinnerDate.invalidateDisplayList();
			_spinnerDate.addEventListener(SpinnerEvent.SPINNER_COMPLETE, onDateChange );
			addSpinner( _spinnerDate );
		}
		
		
		
		//-----------------------------------------------------------------------------------
		// life cycle functions
		//-----------------------------------------------------------------------------------
		
		/**
		 * createChildren
		 */		
		override public function createChildren():void
		{
			super.createChildren();
		}
		
		
		/**
		 * createComplete
		 */		
		override public function creationComplete():void
		{
			super.creationComplete();
			
		}
		
		
		/**
		 * add
		 */		
		override public function add():void
		{
			super.add();
		}
		
		
		/**
		 * remove
		 */		
		override public function remove():void
		{
			super.remove();
		}
		
		
		/**
		 * destroy
		 */		
		override public function destroy():void
		{
			
			_currentYear = NaN;
			_currentMonth = NaN;
			_currentDate = NaN;
			
			if( _spinnerYear )
			{
				_spinnerYear.removeEventListener(SpinnerEvent.SPINNER_COMPLETE, onYearChange );
				_spinnerYear = null;
			}
			
			if( _spinnerMonth )
			{
				_spinnerMonth.removeEventListener(SpinnerEvent.SPINNER_COMPLETE, onMonthChange );
				_spinnerMonth = null;
			}
			
			if( _spinnerDate )
			{
				_spinnerDate.removeEventListener(SpinnerEvent.SPINNER_COMPLETE, onDateChange );
				_spinnerDate = null;
			}
			
			
			super.destroy();
		}
		
		//-----------------------------------------------------------------------------------
		// setter / getter
		//-----------------------------------------------------------------------------------
		
		
		/**
		 * @return 
		 */		
		public function get currentDate():Number
		{
			return _currentDate;
		}
		
		/**
		 * @param value
		 */		
		public function set currentDate(value:Number):void
		{
			_currentDate = value;
		}
		
		/**
		 * @return 
		 */		
		public function get currentMonth():Number
		{
			return _currentMonth;
		}
		
		/**
		 * @param value
		 */		
		public function set currentMonth(value:Number):void
		{
			_currentMonth = value;
		}
		
		/**
		 * @return 
		 */		
		public function get currentYear():Number
		{
			return _currentYear;
		}
		
		/**
		 * @param value
		 */		
		public function set currentYear(value:Number):void
		{
			_currentYear = value;
		}

		
		//-----------------------------------------------------------------------------------
		// protected functions
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		// internal functions
		//-----------------------------------------------------------------------------------
		
		
		
		
		//-----------------------------------------------------------------------------------
		// private functions
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		// event handler
		//-----------------------------------------------------------------------------------
		
		/**
		 * @param e
		 */		
		protected function onYearChange(e:SpinnerEvent):void
		{
			_currentYear = Number( e.currentData );
			
			
			if( _spinnerDate )
			{
				var i : int, len : int, dp : Array;
				
				dp = [];
				i=0;
				len = int( DateUtil.getLastDateAtMonth( _currentMonth, _currentYear ) );
				
				if( len != _spinnerDate.dataProvider.length )
				{
					while( i<len )
					{
						dp.push( String( i+1 ) );
						++i;
					}
					
					_spinnerDate.dataProvider = dp;
					
					if( Number( _spinnerDate.selectedData ) > Number( dp[ dp.length-1 ] ) )
					{
						_spinnerDate.selectedData = dp[ dp.length-1 ];
					}
					
					_spinnerDate.invalidateDisplayList();
				}
			}
		}	
		
		/**
		 * @param e
		 */		
		protected function onMonthChange(e:SpinnerEvent):void
		{
			_currentMonth = Number( e.currentData )-1;
			
			if( _spinnerDate )
			{
				var i : int, len : int, dp : Array;
				
				dp = [];
				i=0;
				len = int( DateUtil.getLastDateAtMonth( _currentMonth, _currentYear ) );
				
				if( len != _spinnerDate.dataProvider.length )
				{
					while( i<len )
					{
						dp.push( String( i+1 ) );
						++i;
					}
					
					_spinnerDate.dataProvider = dp;
					
					if( Number( _spinnerDate.selectedData ) > Number( dp[ dp.length-1 ] ) )
					{
						_spinnerDate.selectedData = dp[ dp.length-1 ];
					}
					
					_spinnerDate.invalidateDisplayList();
				}
			}
		}
		
		/**
		 * @param e
		 */		
		protected function onDateChange(e:SpinnerEvent):void
		{
			_currentDate = Number( e.currentData );
		}		
		
		
		
	}
}